package com.ibeeking.found.msg.rest.service.impl;


import com.ibeeking.found.common.constants.WxMpConstant;
import com.ibeeking.found.common.enums.PublishStatusEnum;
import com.ibeeking.found.common.utils.UserUtils;
import com.ibeeking.found.msg.rest.service.IWxMpAutoReturnMessageService;
import com.ibeeking.found.msg.service.common.constants.RedisKeyConstant;
import com.ibeeking.found.msg.service.common.dos.WxMpAutoReturnMessageDO;
import com.ibeeking.found.msg.service.common.param.WxMpAutoReturnMessageParam;
import com.ibeeking.found.msg.service.common.query.WxMpAutoReturnMessagePageQuery;
import com.ibeeking.found.msg.service.common.query.WxMpAutoReturnMessageQuery;
import com.ibeeking.found.msg.service.common.vo.WxMpAutoReturnMessageVO;
import com.ibeeking.found.msg.service.mapper.WxMpAutoReturnMessageMapper;
import com.ibeeking.nematos.exception.BusinessException;
import com.ibeeking.nematos.redis.utils.RedisUtils;
import com.ibeeking.nematos.utils.data.Collections3;
import com.ibeeking.nematos.utils.data.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ibeeking.nematos.utils.bean.BeanUtil;
import com.ibeeking.nematos.utils.json.JsonUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @ClassName WxMpAutoReturnMessageServiceImpl
 * @Description
 * @Author ibeeking
 * @Date 2021-01-25 15:36
 **/
@Service
@Deprecated
public class WxMpAutoReturnMessageServiceImpl extends ServiceImpl<WxMpAutoReturnMessageMapper, WxMpAutoReturnMessageDO> implements IWxMpAutoReturnMessageService {

    @Resource
    private WxMpAutoReturnMessageMapper wxmpAutoReturnMessageMapper;

    @Resource
    private RedisUtils redis;

    @Override
    public List<WxMpAutoReturnMessageVO> list(WxMpAutoReturnMessageQuery query) {
        List<WxMpAutoReturnMessageDO> wxMpAutoReturnMessageDOS = wxmpAutoReturnMessageMapper.selectList(new LambdaQueryWrapper<WxMpAutoReturnMessageDO>());
        return JsonUtils.jsonToList(wxMpAutoReturnMessageDOS, WxMpAutoReturnMessageVO.class);
    }

    @Override
    public Page<WxMpAutoReturnMessageVO> pageList(WxMpAutoReturnMessagePageQuery pageQuery) {
        Page<WxMpAutoReturnMessageDO> pages = new Page(pageQuery.getPageNum(), pageQuery.getPageSize());
        QueryWrapper<WxMpAutoReturnMessageDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(WxMpAutoReturnMessageDO::getAppId, pageQuery.getAppId())
                .eq(WxMpAutoReturnMessageDO::getType, pageQuery.getType());
        if (WxMpConstant.MESSAGE_EVENT_KEY.equals(pageQuery.getType())) {
            queryWrapper.lambda().eq(StringUtils.isNotBlank(pageQuery.getKeyRule()), WxMpAutoReturnMessageDO::getKeyRule, pageQuery.getKeyRule())
                    .eq(StringUtils.isNotBlank(pageQuery.getKeyWord()), WxMpAutoReturnMessageDO::getKeyWord, pageQuery.getKeyWord());
        }
        pages = wxmpAutoReturnMessageMapper.selectPage(pages, queryWrapper);
        Page<WxMpAutoReturnMessageVO> voPage = BeanUtil.convertBean(pages, Page.class);

        if (Collections3.isNotEmpty(pages.getRecords())) {
            voPage.setRecords(pages.getRecords().stream().map( val -> {
                WxMpAutoReturnMessageVO wxmpAutoReturnMessageVO = new WxMpAutoReturnMessageVO();
                BeanUtils.copyProperties(val,wxmpAutoReturnMessageVO);
                if(WxMpConstant.MESSAGE_EVENT_KEY.equals(val.getType())) {
                    wxmpAutoReturnMessageVO.setKeyWord(Arrays.asList(StringUtils.split(val.getKeyWord(), ",")));
                }
                return wxmpAutoReturnMessageVO;
            }).collect(Collectors.toList()));
        }
        return voPage;

    }



    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean add(WxMpAutoReturnMessageParam param) {
        Long userId = UserUtils.getUserId();
        String keyJoin = null;
        if (WxMpConstant.MESSAGE_EVENT_KEY.equals(param.getType())) {
            keyJoin = this.checkKey(param);
        }
        WxMpAutoReturnMessageDO wxmpAutoReturnMessageDO = BeanUtil.convertBean(param, WxMpAutoReturnMessageDO.class);
        wxmpAutoReturnMessageDO.setKeyWord(keyJoin);
        wxmpAutoReturnMessageDO.setCreateBy(userId);
        wxmpAutoReturnMessageDO.setCreateTime(LocalDateTime.now());
        wxmpAutoReturnMessageDO.setModifyTime(LocalDateTime.now());
        return wxmpAutoReturnMessageMapper.insert(wxmpAutoReturnMessageDO) > 0;
    }

    @Override
    public Boolean modify(WxMpAutoReturnMessageParam param) {
        Long userId = UserUtils.getUserId();
        String keyJoin = null;
        WxMpAutoReturnMessageDO check = wxmpAutoReturnMessageMapper.selectById(param.getId());
        if (check != null) {
            PublishStatusEnum.statusCheckException(check.getPublishStatus());
        }
        if (WxMpConstant.MESSAGE_EVENT_KEY.equals(param.getType())) {
            keyJoin = this.checkKey(param);
        }
        WxMpAutoReturnMessageDO wxmpAutoReturnMessageDO = BeanUtil.convertBean(param, WxMpAutoReturnMessageDO.class);
        wxmpAutoReturnMessageDO.setKeyWord(keyJoin);
        wxmpAutoReturnMessageDO.setModifyBy(userId);
        wxmpAutoReturnMessageDO.setModifyTime(LocalDateTime.now());
        return wxmpAutoReturnMessageMapper.updateById(wxmpAutoReturnMessageDO) > 0;
    }

    @Override
    public WxMpAutoReturnMessageVO view(Long id) {
        WxMpAutoReturnMessageDO wxmpAutoReturnMessageDO = wxmpAutoReturnMessageMapper.selectById(id);
        String keys = wxmpAutoReturnMessageDO.getKeyWord();
        WxMpAutoReturnMessageVO vo = BeanUtil.convertBean(wxmpAutoReturnMessageDO, WxMpAutoReturnMessageVO.class);
        if (StringUtils.isNotBlank(keys)) {
            List<String> keyArray = Arrays.asList(StringUtils.split(","));
            vo.setKeyWord(keyArray);
        }
        return vo;
    }

    @Override
    public Boolean changeStatus(Long id, Integer status) {
        String key = "key";
        WxMpAutoReturnMessageDO wxmpAutoReturnMessageDO = new WxMpAutoReturnMessageDO();
        wxmpAutoReturnMessageDO.setId(id);
        wxmpAutoReturnMessageDO.setPublishStatus(status);
        wxmpAutoReturnMessageDO.setModifyTime(LocalDateTime.now());
        if (wxmpAutoReturnMessageMapper.updateById(wxmpAutoReturnMessageDO) > 0) {
            WxMpAutoReturnMessageDO message = this.wxmpAutoReturnMessageMapper.selectById(id);
            if (message == null) {
                throw new BusinessException("发布状态修改失败");
            }
            if (StringUtils.isBlank(message.getKeyWord())) {
                throw new BusinessException("发布状态修改失败");
            }
            //无用字段值删除,节省缓存空间
            message.setKeyWord(null).setPublishStatus(null).setKeyRule(null).setCreateBy(null)
                    .setModifyBy(null).setDelStatus(null).setCreateTime(null).setModifyTime(null);
            //判断发布类型
            if (key.equals(message.getType())) {
                List<String> keys = Arrays.asList(StringUtils.split(message.getKeyWord(), ","));
                if (Collections3.isEmpty(keys)) {
                    throw new BusinessException("发布状态修改失败");
                }
                //判断如果是发布将字段保存到缓存
                if (PublishStatusEnum.ENABLE.getValue().equals(status)) {
                    keys.stream().forEach(o -> {
                        StringBuilder sb = new StringBuilder();
                        String redisKey = sb.append(RedisKeyConstant.MODULE).append(message.getAppId()).append(":").append(RedisKeyConstant.MP_KEY_SEND).append(WxMpConstant.MESSAGE_TEXT)
                                .append(":").append(o.trim()).toString();
                        redis.set(redisKey, message);
                    });
                } else if (PublishStatusEnum.DISABLE.getValue().equals(status)) {
                    keys.stream().forEach(o -> {
                        StringBuilder sb = new StringBuilder();
                        String redisKey = sb.append(RedisKeyConstant.MODULE).append(message.getAppId()).append(":").append(RedisKeyConstant.MP_KEY_SEND).append(WxMpConstant.MESSAGE_TEXT)
                                .append(":").append(o.trim()).toString();
                        redis.del(redisKey);
                    });
                } else {
                    throw new BusinessException("发布状态错误");
                }
            } else {
                if (PublishStatusEnum.ENABLE.getValue().equals(status)) {
                    StringBuilder sb = new StringBuilder();
                    String redisKey = sb.append(RedisKeyConstant.MODULE).append(message.getAppId()).append(":")
                            .append(message.getType()).toString();
                    redis.set(redisKey, message);
                    QueryWrapper<WxMpAutoReturnMessageDO> queryWrapper = new QueryWrapper<>();
                    queryWrapper.lambda().eq(WxMpAutoReturnMessageDO::getAppId, message.getAppId())
                            .eq(WxMpAutoReturnMessageDO::getType, message.getType())
                            .ne(WxMpAutoReturnMessageDO::getId, id);
                    WxMpAutoReturnMessageDO update = new WxMpAutoReturnMessageDO();
                    update.setPublishStatus(PublishStatusEnum.DISABLE.getValue());
                    update.setModifyTime(LocalDateTime.now());
                    this.wxmpAutoReturnMessageMapper.update(update, queryWrapper);
                } else {
                    StringBuilder sb = new StringBuilder();
                    String redisKey = sb.append(RedisKeyConstant.MODULE).append(message.getAppId()).append(":")
                            .append(message.getType()).toString();
                    redis.del(redisKey);
                }
            }
        }
        return true;

    }

    @Override
    public Boolean del(Long id) {
        WxMpAutoReturnMessageDO wxmpAutoReturnMessageDO = this.wxmpAutoReturnMessageMapper.selectById(id);
        PublishStatusEnum.statusCheckException(wxmpAutoReturnMessageDO.getPublishStatus());
        return wxmpAutoReturnMessageMapper.deleteById(id) > 0;
    }


    @Override
    public Boolean checkName(String keyRule, String keyWord, Long id) {
        QueryWrapper<WxMpAutoReturnMessageDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(StringUtils.isNotBlank(keyRule), WxMpAutoReturnMessageDO::getKeyRule, keyRule)
                .or().eq(StringUtils.isNotBlank(keyWord), WxMpAutoReturnMessageDO::getKeyWord, keyWord)
                .ne(id != null, WxMpAutoReturnMessageDO::getId, id);
        List<WxMpAutoReturnMessageDO> list = this.wxmpAutoReturnMessageMapper.selectList(queryWrapper);
        if (Collections3.isEmpty(list)) {
            return false;
        }
        return true;
    }


    /**
     * 修改除关键字以外的自动回复
     *
     * @param param
     * @return
     */
    @Override
    public Boolean saveOther(WxMpAutoReturnMessageParam param) {
        Long userId = UserUtils.getUserId();
        String type = param.getType();
        String key = "key";
        if (key.equals(type)) {
            throw new BusinessException("保存类型不匹配");
        }
        String returnType = "text";
        if (returnType.equals(param.getReturnType())) {
            if (StringUtils.isBlank(param.getContent())) {
                throw new BusinessException("文字回复不能回复空内容");
            } else {
                if (param.getContent().length() > 600) {
                    throw new BusinessException("文字回复不能超过600字");
                }
            }
        }
        WxMpAutoReturnMessageDO messageDO = BeanUtil.convertBean(param, WxMpAutoReturnMessageDO.class);
        boolean flag = false;
        if (param.getId() == null) {
            messageDO.setCreateBy(userId);
            messageDO.setCreateTime(LocalDateTime.now());
            messageDO.setModifyTime(LocalDateTime.now());
            flag = this.wxmpAutoReturnMessageMapper.insert(messageDO) > 0;
        } else {
            messageDO.setModifyBy(userId);
            messageDO.setModifyTime(LocalDateTime.now());
            flag = this.wxmpAutoReturnMessageMapper.updateById(messageDO) > 0;
        }

        return flag;
    }

    private String checkKey(WxMpAutoReturnMessageParam param) {
        String keyJoin = null;
        if (Collections3.isEmpty(param.getKeyWord())) {
            List<String> keys = new ArrayList<>();
            keys.add(param.getKeyName());
            throw new BusinessException("关键字不能为空");
        }
        if (param.getKeyWord().size() > 10) {
            throw new BusinessException("关键字最大支持10个");
        }
        if (StringUtils.isNotBlank(param.getKeyRule())) {
            if (param.getKeyRule().length() > 60) {
                throw new BusinessException("规则名称最多60个字");
            }
        } else {
            throw new BusinessException("规则名称不能为空");
        }
        List<String> keys = new ArrayList<>();
        for (String keyWord : param.getKeyWord()) {
            if (StringUtils.isNotBlank(keyWord)) {
                if (keyWord.length() > 30) {
                    throw new BusinessException("关键字不能为空");
                } else {
                    keys.add(keyWord);
                }
            } else {
                throw new BusinessException("关键字不能为空");
            }
        }
        if (Collections3.isEmpty(keys)) {
            throw new BusinessException("关键字不能为空");
        }
        keyJoin = keys.stream().collect(Collectors.joining(", "));
        if (this.checkName(param.getKeyRule(), keyJoin, param.getId())) {
            throw new BusinessException("关键字或规则名称不能重复");

        }
        return keyJoin;
    }
}
